package com.egg.demo.secure;

import cn.hutool.json.JSONUtil;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.util.SecureUtil;
import com.egg.demo.secure.annotation.Encrypt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;


@Slf4j
@ControllerAdvice
public class EncryptResponseAdvice implements ResponseBodyAdvice<ResponseData> {


    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 只有接口上加了@Encrypt注解才进行出参加密操作
        return returnType.hasMethodAnnotation(Encrypt.class);
    }

    @Override
    public ResponseData beforeBodyWrite(
            ResponseData body
            , MethodParameter returnType
            , MediaType selectedContentType
            , Class<? extends HttpMessageConverter<?>> selectedConverterType
            , ServerHttpRequest request, ServerHttpResponse response
    ) {
        try {
            if (body.getData() != null) {
                // 对称秘钥，可以从数据库或缓存中获取，这里暂时写死
                String aes = "对称秘钥凑满32位:12345678";
                // aesEncrypt 内的 getSecretKey(key) 秘钥必须为 32位或者16为，
                // aesEncrypt 内的 getSecureRandomSecretKey(key) 任意秘钥
                String encStr = SecureUtil.aesEncrypt(aes, JSONUtil.toJsonStr(body.getData()));
                body.setData(encStr);
            }
        } catch (Exception e) {
            log.error("加密数据失败", e);
        }
        return body;
    }


}